//
//  ViewController.m
//  SaIios
//
//  Created by wolfchen on 18/5/24.
//  Copyright (c) 2018年 wolfchen. All rights reserved.
//

#import "ViewController.h"
#import<MobileCoreServices/MobileCoreServices.h>
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#import <opencv2/opencv.hpp>
#import <opencv2/imgproc/types_c.h>
#import <opencv2/imgcodecs/ios.h>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
   int hh[12000000],ww[12000000];
//int fennum[6];
bool GG=true;
UIImage *imagetest;
UIImage *image1;
UIImage *quanjing=NULL;
using namespace cv;
@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@property (strong, nonatomic) IBOutlet UILabel *al;
@property (strong, nonatomic) IBOutlet UIImageView *imageview1;
@property(strong,nonatomic) UIImagePickerController *imagePickercon;
@property(strong,nonatomic) UIImagePickerController *imagePickercon1;
@property (strong, nonatomic) IBOutlet UIImageView *imageview;
@end
void fft2(IplImage *src, IplImage *dst)
{
    IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0;
    image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
    image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
    Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);
    cvConvertScale(src, image_Re, 1, 0);
    cvZero(image_Im);
    cvMerge(image_Re, image_Im, 0, 0, Fourier);
    cvDFT(Fourier, dst, CV_DXT_FORWARD);
    cvReleaseImage(&image_Re);
    cvReleaseImage(&image_Im);
    cvReleaseImage(&Fourier);
}


@implementation ViewController
-(UIImagePickerController *)imagePickercon{
    if(!_imagePickercon){
        _imagePickercon=[[UIImagePickerController alloc] init];
        _imagePickercon.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
        //_imagePickercon.mediaTypes=[NSArray arrayWithObject:(__bridge NSString *)kUTTypeImage];
        _imagePickercon.delegate=self;
    }
    return _imagePickercon;
}
-(UIImagePickerController *)imagePickercon1{
    if(!_imagePickercon1){
        _imagePickercon1=[[UIImagePickerController alloc] init];
        _imagePickercon1.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
        //_imagePickercon.mediaTypes=[NSArray arrayWithObject:(__bridge NSString *)kUTTypeImage];
        _imagePickercon1.delegate=self;
    }
    return _imagePickercon1;
}
- (IBAction)button:(id)sender {
    GG=true;
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
        self.imagePickercon.sourceType=UIImagePickerControllerSourceTypeCamera;
    }
    if(quanjing!=NULL){
        self.imageview1.image=quanjing;
    }
    [self presentViewController:self.imagePickercon animated:YES completion:nil];
}
- (void)saveImageToPhotos:(UIImage*)savedImage
{
    UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}
- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
{
    NSString *msg = nil ;
    if(error != NULL){
        msg = @"保存图片失败" ;
    }else{
        msg = @"保存图片成功" ;}
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
    _okAction1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) {
       
    }];
    [alert addAction:_okAction];
    [self showViewController:alert sender:nil];
}
- (IBAction)button3:(id)sender {
    [self saveImageToPhotos:image1];
}

- (IBAction)button2:(id)sender {
    GG=false;
       [self showError];
}
-(void)showError{
      UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"请确保相册中有你想拍风景的全景图！" preferredStyle:UIAlertControllerStyleAlert];
    _okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) {
        self.imagePickercon.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
        [self presentViewController:self.imagePickercon animated:YES completion:nil];
        
    }];
    [alert addAction:_okAction];
    [self presentViewController:alert animated:true completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    char ss[3];
    if(GG==true)
    {
        image1 =info[UIImagePickerControllerOriginalImage];
        CGSize imageSize = image1.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
        CGFloat widthFactor = 1024/ width;
        CGFloat heightFactor = 768/ height;
        CGFloat scaleFactor = (widthFactor<heightFactor?widthFactor:heightFactor);
        
        CGFloat scaledWidth = width * scaleFactor;
        CGFloat scaledHeight = height * scaleFactor;
        CGSize targetSize = CGSizeMake(scaledWidth,scaledHeight);
        
        UIGraphicsBeginImageContext(targetSize);
        [image1 drawInRect:CGRectMake(0,0,scaledWidth,scaledHeight)];
        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIImage *image=newImage;
        
        Mat cvImage,sal;
        UIImageToMat(image, cvImage);
        IplImage *src, *ImageRe, *ImageIm, *Fourier, *Inverse, *LogAmplitude, *Sine, *Cosine;
        IplImage *Saliency, *Residual;
        IplImage *tmp1, *tmp2, *tmp3;
        double minNum = 0, maxNum = 0, scale, shift;
        int  nRow, nCol;
        IplImage imgTmp = cvImage;
        IplImage *srcColor = cvCloneImage(&imgTmp);
        src = cvCreateImage(cvGetSize(srcColor), IPL_DEPTH_8U, 1);
        cvCvtColor(srcColor,src,CV_BGR2GRAY);
        Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);
        Inverse = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);
        ImageRe = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        ImageIm = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        
        LogAmplitude = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        Sine = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        Cosine = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        
        Residual = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        Saliency = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
        tmp1 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        tmp2 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        tmp3 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
        
        nRow = src->height;
        nCol = src->width;
        
        scale = 1.0/255.0;
        cvConvertScale(src, tmp1, scale, 0);
        fft2(tmp1, Fourier);
        
        cvSplit(Fourier, ImageRe, ImageIm, 0, 0);
        cvPow( ImageRe, tmp1, 2.0);
        cvPow( ImageIm, tmp2, 2.0);
        cvAdd( tmp1, tmp2, tmp3);
        cvPow( tmp3, tmp3, 0.5 );
        cvLog( tmp3, LogAmplitude );
        cvDiv(ImageIm, tmp3, Sine);
        cvDiv(ImageRe, tmp3, Cosine);
        cvSmooth(LogAmplitude, tmp3, CV_BLUR, 3, 3);
        cvSub(LogAmplitude, tmp3, Residual);
        cvExp(Residual, Residual);
        cvMul(Residual, Cosine, tmp1);
        cvMul(Residual, Sine, tmp2);
        cvMerge(tmp1, tmp2, 0, 0, Fourier);
        cvDFT(Fourier, Inverse, CV_DXT_INV_SCALE);
        cvSplit(Inverse ,tmp1, tmp2,0,0);
        cvPow(tmp1, tmp1, 2);
        cvPow(tmp2, tmp2, 2);
        cvAdd(tmp1, tmp2, tmp3, NULL);
        cvSmooth(tmp3, tmp3, CV_GAUSSIAN, 7, 7);
        cvMinMaxLoc(tmp3, &minNum, &maxNum, NULL, NULL);
        scale = 255/(maxNum - minNum);
        shift = -minNum * scale;
        cvConvertScale(tmp3, Saliency, scale, shift);
        cvReleaseImage(&src);
        cvReleaseImage(&ImageIm);
        cvReleaseImage(&ImageRe);
        cvReleaseImage(&Fourier);
        cvReleaseImage(&Inverse);
        cvReleaseImage(&LogAmplitude);
        cvReleaseImage(&Sine);
        cvReleaseImage(&Cosine);
        
        cvReleaseImage(&Residual);
        cvReleaseImage(&tmp1);
        cvReleaseImage(&tmp2);
        cvReleaseImage(&tmp3);
        Mat mtest = cvarrToMat(Saliency,true);
        cvReleaseImage(&Saliency);
        int num=0;
        int hig=0,wid=0;
        int min,max;
        int fen;
        int a=mtest.rows/3,s=mtest.cols/3,d=a*2,f=s*2;
        
        for (int row = 0; row < mtest.rows; row++)
        {
            for (int col = 0; col < mtest.cols; col++)
            {
                if(mtest.at<Vec3b>(row,col)[0] !=0 && mtest.at<Vec3b>(row,col)[1] !=0 && mtest.at<Vec3b>(row,col)[2] !=0)
                {
                    hh[num]=row;
                    ww[num]=col;
                    num++;
                }
            }
        }
        for(int i=0;i<num;i++)
        {
            hig+=hh[i];
        }
        hig=hig/num;
        for(int i=0;i<num;i++)
        {
            wid+=ww[i];
        }
        wid=wid/num;
        min= (a-hig)*(a-hig)+(s-wid)*(s-wid);
        if(min>(a-hig)*(a-hig)+(f-wid)*(f-wid))
            min=(a-hig)*(a-hig)+(f-wid)*(f-wid);
        if(min>(d-hig)*(d-hig)+(f-wid)*(f-wid))
            min=(d-hig)*(d-hig)+(f-wid)*(f-wid);
        if(min>(d-hig)*(d-hig)+(s-wid)*(s-wid))
            min=(d-hig)*(d-hig)+(s-wid)*(s-wid);
        min=sqrt(min);
        max=a*a+s*s;
        max=sqrt(max);
        fen=min*100/max;
        fen=100-fen;
        if(fen<0){
            fen=-fen;
        }
        if(fen<50){
            fen=fen-14;
        }
        if(fen<75&&fen>55)
        {
            fen=fen+23;
        }
        if(fen>90){
            fen=fen-4;
        }
        sprintf(ss, "%d", fen);
        CvFont font;
        double hScale=2;
        double vScale=2;
        int lineWidth=5;
        cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
        
        Mat asdd;
        UIImageToMat(image, asdd);
        IplImage eee = asdd;
        cvPutText(&eee,ss,cvPoint(0,60),&font,CV_RGB(0,0,255));//在图片中输出字符
        Mat asd = cvarrToMat(&eee,true);
        imagetest = MatToUIImage(asd);
        self.imageview.image=imagetest;
    //}
    [self dismissViewControllerAnimated:YES
                             completion:nil];
    }
    else{
          image1 =info[UIImagePickerControllerOriginalImage];
        UIImage *getImage;
        NSMutableArray *arr = [[NSMutableArray alloc] init];
        NSMutableArray *fennum = [[NSMutableArray alloc] init];
        CGSize imageSize = image1.size;
        CGFloat width = imageSize.width;
        CGFloat height = imageSize.height;
        int flag;
        flag=height*1.777;
        int zaza=0;
        zaza=width/flag;
        int lalalala;
        for(lalalala=0;lalalala<zaza;lalalala++){
            CGImageRef imageRef = CGImageCreateWithImageInRect(image1.CGImage, CGRectMake(lalalala*flag, 0, flag, height));
            getImage = [UIImage imageWithCGImage:imageRef];
            NSData *_data =UIImageJPEGRepresentation(getImage, 1.0f);
            NSString *_encodedImageStr = [_data base64Encoding];
            [arr addObject:_encodedImageStr];
            CGSize imageSize = getImage.size;
            CGFloat width = imageSize.width;
            CGFloat height = imageSize.height;
            CGFloat widthFactor = 768/ width;
            CGFloat heightFactor =1024/ height;
            CGFloat scaleFactor = (widthFactor<heightFactor?widthFactor:heightFactor);
            
            CGFloat scaledWidth = width * scaleFactor;
            CGFloat scaledHeight = height * scaleFactor;
            CGSize targetSize = CGSizeMake(scaledWidth,scaledHeight);
            
            UIGraphicsBeginImageContext(targetSize);
            [image1 drawInRect:CGRectMake(0,0,scaledWidth,scaledHeight)];
            UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
            UIImage *image=newImage;
            Mat cvImage,sal;
            UIImageToMat(image, cvImage);
            IplImage *src, *ImageRe, *ImageIm, *Fourier, *Inverse, *LogAmplitude, *Sine, *Cosine;
            IplImage *Saliency, *Residual;
            IplImage *tmp1, *tmp2, *tmp3;
            double minNum = 0, maxNum = 0, scale, shift;
            int  nRow, nCol;
            IplImage imgTmp = cvImage;
            IplImage *srcColor = cvCloneImage(&imgTmp);
            src = cvCreateImage(cvGetSize(srcColor), IPL_DEPTH_8U, 1);
            cvCvtColor(srcColor,src,CV_BGR2GRAY);

            Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);
            Inverse = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);
            ImageRe = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            ImageIm = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            LogAmplitude = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            Sine = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            Cosine = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            Residual = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            //特征map(Saliency map)
            Saliency = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
            tmp1 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            tmp2 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            tmp3 = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);
            
            nRow = src->height;
            nCol = src->width;
            

            scale = 1.0/255.0;
            cvConvertScale(src, tmp1, scale, 0);
            

            fft2(tmp1, Fourier);
            

            cvSplit(Fourier, ImageRe, ImageIm, 0, 0);
            

            cvPow( ImageRe, tmp1, 2.0);
            cvPow( ImageIm, tmp2, 2.0);
            cvAdd( tmp1, tmp2, tmp3);
            cvPow( tmp3, tmp3, 0.5 );
            

            cvLog( tmp3, LogAmplitude );
            cvDiv(ImageIm, tmp3, Sine);
            cvDiv(ImageRe, tmp3, Cosine);
            

            cvSmooth(LogAmplitude, tmp3, CV_BLUR, 3, 3);
            

            cvSub(LogAmplitude, tmp3, Residual);
            
            cvExp(Residual, Residual);
            cvMul(Residual, Cosine, tmp1);
            cvMul(Residual, Sine, tmp2);
            

            cvMerge(tmp1, tmp2, 0, 0, Fourier);
            

            cvDFT(Fourier, Inverse, CV_DXT_INV_SCALE);
            
            cvSplit(Inverse ,tmp1, tmp2,0,0);

            cvPow(tmp1, tmp1, 2);
            cvPow(tmp2, tmp2, 2);
            cvAdd(tmp1, tmp2, tmp3, NULL);
            

            cvSmooth(tmp3, tmp3, CV_GAUSSIAN, 7, 7);
            
            cvMinMaxLoc(tmp3, &minNum, &maxNum, NULL, NULL);
            scale = 255/(maxNum - minNum);
            shift = -minNum * scale;
            

            cvConvertScale(tmp3, Saliency, scale, shift);
            

            cvReleaseImage(&src);
            cvReleaseImage(&ImageIm);
            cvReleaseImage(&ImageRe);
            cvReleaseImage(&Fourier);
            cvReleaseImage(&Inverse);
            cvReleaseImage(&LogAmplitude);
            cvReleaseImage(&Sine);
            cvReleaseImage(&Cosine);
            
            cvReleaseImage(&Residual);
            cvReleaseImage(&tmp1);
            cvReleaseImage(&tmp2);
            cvReleaseImage(&tmp3);
            
            //cvDestroyAllWindows();
            
            Mat mtest = cvarrToMat(Saliency,true);
            cvReleaseImage(&Saliency);
            int num=0;
            int hig=0,wid=0;
            int min,max;
            int fen;
            
            int a=mtest.rows/3,s=mtest.cols/3,d=a*2,f=s*2;
            
            for (int row = 0; row < mtest.rows; row++)
            {
                for (int col = 0; col < mtest.cols; col++)
                {
                    if(mtest.at<Vec3b>(row,col)[0] !=0 && mtest.at<Vec3b>(row,col)[1] !=0 && mtest.at<Vec3b>(row,col)[2] !=0)
                    {
                        hh[num]=row;
                        ww[num]=col;
                        num++;
                    }
                }
            }
            for(int i=0;i<num;i++)
            {
                hig+=hh[i];
            }
            hig=hig/num;
            for(int i=0;i<num;i++)
            {
                wid+=ww[i];
            }
            wid=wid/num;
            min= (a-hig)*(a-hig)+(s-wid)*(s-wid);
            if(min>(a-hig)*(a-hig)+(f-wid)*(f-wid))
                min=(a-hig)*(a-hig)+(f-wid)*(f-wid);
            if(min>(d-hig)*(d-hig)+(f-wid)*(f-wid))
                min=(d-hig)*(d-hig)+(f-wid)*(f-wid);
            if(min>(d-hig)*(d-hig)+(s-wid)*(s-wid))
                min=(d-hig)*(d-hig)+(s-wid)*(s-wid);
            min=sqrt(min);
            max=a*a+s*s;
            max=sqrt(max);
            fen=min*100/max;
            fen=100-fen;
            if(fen<0){
                fen=-fen;
            }
            if(fen<50){
                fen=fen-14;
            }
            if(fen<75&&fen>55)
            {
                fen=fen+23;
            }
            if(fen>90){
                fen=fen-4;
            }
            fennum[lalalala]=@(fen);

        }
        int max_number=0;
        int max_index=0;
        for (int i = 0; i<zaza; i++) {

            int v = [fennum[i] integerValue];
            if (v > max_number) {
                max_index = i;
            }
            max_number = v>max_number?v:max_number;
        }
        NSData *_decodedImageData = [[NSData alloc] initWithBase64Encoding:arr[max_index]];
        UIImage *_decodedImage = [UIImage imageWithData:_decodedImageData];
        sprintf(ss, "%d", max_number);
        CvFont font;
        double hScale=2;
        double vScale=2;
        int lineWidth=6;   
        cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);//初始化字体，准备写到图片上的
        // cvPoint 为起笔的x，y坐标
        
        Mat asdd;
        UIImageToMat(_decodedImage, asdd);
        IplImage eee = asdd;
        cvPutText(&eee,ss,cvPoint(0,60),&font,CV_RGB(0,0,255));//在图片中输出字符
        Mat asd = cvarrToMat(&eee,true);
        imagetest = MatToUIImage(asd);
        self.imageview.image=imagetest;
        self.imageview1.image=NULL;
        quanjing=imagetest;
        [self dismissViewControllerAnimated:NO
                                 completion:nil];
    }
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    NSLog(@"取消采集图片");
    [self dismissViewControllerAnimated:YES completion:nil];
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end
